/********** 过程作为参数 lambda构造 **********/
// 3, 9
function sumOfInts(a, b) {
  if (a > b) return 0;
  return a + sumOfInts(a + 1, b);
}

function cube(x) {
  return x ** 3;
}

// 3, 9
function sumOfCubes(a, b, cube) {
  if (a > b) return 0;
  return cube(3) + sumOfCubes(a + 1, b);
}

// 一等公民
function sumOfTerms(a, b, term = x => x, next = x => x + 1) {
  if (a > b) return 0;
  return term(a) + sumOfTerms(next(a), b);
}

sumOfTerms(1, 10, x => x ** 3);

// 加法变乘法
function product(a, b, term, next) {
  if (a > b) return 1;
  return term(a) * product(next(a), b, next, term);
}

// 更抽象
// 练习：递归转迭代
function reduce(a, b, next, term, combiner, emptyValue) {
  if (a > b) return emptyValue;
  return combiner(
    term(a),
    reduce(next(a), b, next, term, combiner, emptyValue)
  );
}

/********** 过程作为结果 **********/

// inc(inc(1));

function double(fn) {
  return function (x) {
    return fn(fn(x));
  };
}

// const kkk2 = function () {};

// const kkk = double(inc);
// console.log(kkk);
// console.log(kkk(1));

const inc = x => x + 1;
const mul = x => x * 2;
const INM = compose(mul, inc)(2);
const MNI = compose(inc, mul);

function compose(f, g, h, k) {
  return x => f(g(h(k(x))));
}

function pipe(...fns) {}

function compose2(...fns) {
  console.log(fns);
  fns.forEach(fn => console.log(fn));
}

compose2(inc, mul);
